using System.Collections;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Events;

/// <summary>
/// 打字机效果脚本：逐字显示文字，并提供打印到字符、进度和完成回调。
/// 点击事件请通过单独挂载 ClickPropagationHandler 并绑定 onClick 来实现。
/// </summary>
[RequireComponent(typeof(Text))]
public class TypewriterEffect : MonoBehaviour
{
    [Header("打字参数")]
    [Tooltip("每个字符打印间隔（秒）")]
    public float charInterval = 0.05f;

    [Header("回调事件")]
    [Tooltip("每打印一个字符就触发，参数为该字符的字符串形式")]
    public UnityEvent<string> onCharacterPrinted;

    [Tooltip("打印进度变化时触发，参数为当前进度（0~1）")]
    public UnityEvent<float> onProgress;

    [Tooltip("打字完成时触发的事件")]
    public UnityEvent onComplete;

    public bool isEnd = true;
    private Text uiText;
    private Coroutine typingCoroutine;
    private string fullText;
    
    void Awake()
    {
        uiText = GetComponent<Text>();
        // 确保文字不拦截射线，点击由 ClickPropagationHandler 管理
        uiText.raycastTarget = false;
    }

    /// <summary>
    /// 开始打字效果，自动停止已有的协程
    /// </summary>
    /// <param name="textToType">要显示的完整文本</param>
    public void StartTyping(string textToType)
    {
        isEnd = false;
        fullText = textToType ?? string.Empty;
        if (typingCoroutine != null)
            StopCoroutine(typingCoroutine);
        typingCoroutine = StartCoroutine(TypeText());
    }

    private IEnumerator TypeText()
    {
        uiText.text = string.Empty;
        int total = fullText.Length;
        for (int i = 0; i < total; i++)
        {
            char c = fullText[i];
            uiText.text += c;
            onCharacterPrinted?.Invoke(c.ToString());
            float progress = (i + 1) / (float)total;
            onProgress?.Invoke(progress);
            yield return new WaitForSeconds(charInterval);
        }
        typingCoroutine = null;
        isEnd = true;
        onComplete?.Invoke();
        
    }

    /// <summary>
    /// 立即完成打字，显示完整文本并触发进度与完成回调
    /// </summary>
    public async void CompleteTyping()
    {
        if (typingCoroutine != null)
        {
            StopCoroutine(typingCoroutine);
            typingCoroutine = null;
        }
        uiText.text = fullText;
        onProgress?.Invoke(1f);
        isEnd = true;
        onComplete?.Invoke();
    }
}
